#pragma once
#include <vector>
#include <string>
#include "Utilities.h"
#include "FileOperator.h"
#include "MyMath.h"

class TwoDimProblem
{
public:
	//////////////////////////////////////////////////////////////////////////
private:
	std::string paraFile;///< the file name of input parameter file
	int gridNumX;///< Nx, grid number of x direction, equals to the max vertex index of x direction
	int gridNumY;///< Ny, grid number of y direction, equals to the max vertex index of y direction
	int vertexNumX;///< Nx+1, vertex number of x direction
	int vertexNumY;///< Ny+1, vertex number of y direction
	std::vector<double> rhs;///< (Nx+1) * (Ny+1)
	Utilities::TwoDimBC leftBoundary;///< the boundary condition of the left boundary
	Utilities::TwoDimBC rightBoudary;///< the boundary condition of the right boundary
	Utilities::TwoDimBC upBoundary;///< the boundary condition of the upper boundary
	Utilities::TwoDimBC downBoundary;///< the boundary conditino of the lower boundary

#pragma region the physical and math parameters in 1-D Poisson problem
	//the number of parameters below equals to (Nx+1) and (Ny+1)
	std::vector<double> meshX;///< Nx+1
	std::vector<double> meshY;///< Ny+1
	//the number of parameters below equals to (Nx+1) * (Ny+1)
	Utilities::My2DVector<double> coordX;///< x Coordinate of Vertex
	Utilities::My2DVector<double> coordY;///< y Coordinate of Vertex
	Utilities::My2DVector<double> potential;
	Utilities::My2DVector<double> elecFieldX;///< electric field of x direction, normalized by V/cm
	Utilities::My2DVector<double> elecFieldY;///< electric field of y direction, normalized by V/cm
	Utilities::My2DVector<double> chargeAtVertex;///< normalized by q*m-1, for 2-D problem
	Utilities::My2DVector<double> elecFieldAbs;///< absolute value of electric field, =(Ex^2 + Ey^2)^0.5
	//the number of parameters below equals to Nx * Ny
	Utilities::My2DVector<double> chargeConc;///< normalized by q*m-3
	Utilities::My2DVector<double> rDielectric;///< relative dielectric constant
	Utilities::My2DVector<double> deltaX;///< the space between adjacent vertex in x direction, normalized by cm
	Utilities::My2DVector<double> deltaY;///< the space between adjacent vertex in y direction, normalized by cm
#pragma endregion
	//////////////////////////////////////////////////////////////////////////
public:
	TwoDimProblem(std::string initFile);
	~TwoDimProblem(void);
	void Solve();
	void OutputResult();
	//////////////////////////////////////////////////////////////////////////
private:
	void normalizeBoundaryConditionValues();
	void initAndNormPhysicalParameter();
	void initRHSVector();
	void refreshRHSVector();
	void solvePotential();
};

